package cn.gcjxsc.payment.task;

import cn.gcjxsc.common.data.wx.CloseOrder;
import cn.gcjxsc.common.data.wx.QueryOrder;
import cn.gcjxsc.payment.data.OrderConfig;
import cn.gcjxsc.payment.data.WeChatConfig;
import cn.gcjxsc.payment.service.wx.WeChatApiService;
import cn.gcjxsc.payment.task.schedule.MySchedule;
import cn.gcjxsc.payment.util.WxUtil;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author pumbaa
 * @since 1.0
 */
@Service
public class OrderTaskService {
    private Logger logger = LoggerFactory.getLogger(OrderTaskService.class);
    @Autowired
    private OrderConfig orderConfig;
    @Autowired
    private MySchedule schedule;
    @Autowired
    private WeChatApiService apiService;
    @Autowired
    private WeChatConfig weChatConfig;

    private class OrderCancelTask implements Runnable{
        private String tradeNo;
        private Integer type;

        public OrderCancelTask(String tradeNo, Integer type)
        {
            this.tradeNo = tradeNo;
            this.type = type;
        }

        /**
         * 回调php发起取消支付操作
         */
        @Override
        public void run() {
            /**
             * 先查询是否存在订单.
             * 1.存在:,发起取消申请,再回调通知
             * 2.不存在: 回调取消通知
             */

            try {
                QueryOrder.QueryOrderResponse queryOrderResponse;
                CloseOrder.CloseOrderResponse response;
                if (type == 1) {
                    queryOrderResponse = apiService.queryOrder(weChatConfig, tradeNo);
                }
                else {
                    queryOrderResponse = apiService.queryOrderByTransactionId(weChatConfig, tradeNo);
                }
                //如果存在订单,且为未支付,发起关闭指令
                if (queryOrderResponse.getReturn_code().equals(WxUtil.SUCCESS) && queryOrderResponse.getResult_code().equals(WxUtil.SUCCESS)) {
                    if (!queryOrderResponse.getTrade_state().equals(WxUtil.NOTPAY)) {
                        response = apiService.closeOrder(weChatConfig, tradeNo);
                        if (null != response) {
                            logger.info("取消结果:{}", response.getReturn_code());
                            if (response.getReturn_code().equals(WxUtil.SUCCESS)) {
                                notifyCancel(tradeNo);
                            }
                        }
                    }
                }
                else {
                    notifyCancel(tradeNo);
                }
            } catch (Exception e) {

            }
            schedule.getScheduledTasks().get(this).cancel(true);
        }

        private void notifyCancel(String tradeNo){
            String url = orderConfig.getOrderCancelUrl();
            CloseableHttpClient httpClient = HttpClients.createDefault();
            HttpPost post = new HttpPost(url);
            List<NameValuePair> params = new ArrayList<>();
            params.add(new BasicNameValuePair("tradeNo", tradeNo));
            try {
                logger.info("回调取消订单:{}, {}", tradeNo, url);
                post.setEntity(new UrlEncodedFormEntity(params, "utf-8"));
                CloseableHttpResponse httpResponse = httpClient.execute(post);
                int statusCode = httpResponse.getStatusLine().getStatusCode();
                logger.info("回调取消结果:{}", statusCode);
            } catch (Exception e) {
                e.printStackTrace();
                logger.error("回调失败: {}", e.getMessage());
            }
        }
    }


    public void cancelOrderTask(String tradeNo, Long min, Integer type){
        OrderCancelTask task = new OrderCancelTask(tradeNo, type);
        Long timestamp = 60 * min * 1000;
        Date date = new Date();
        long startTime = date.getTime() + timestamp;
        logger.info("准备取消订单. {}", tradeNo);
        schedule.scheduleWithFixedDelay(task, new Date(startTime), 20000);
    }
}
